<template>
  <div
    :class="'effect-scatter-map-wrap ' + wrapId"
    :key="wrapId"
    :id="wrapId"
    :ref="wrapId"
    :style="{ height: height, width: width }"
  >
    <div :id="id" :ref="id" :class="'chart ' + className"></div>
  </div>
</template>
<script>
import echarts from 'echarts'
import { isFunction, each, merge, isEmpty, isEqual, isNaN } from 'lodash'
import chartResize from '@/mixins/chartResize'
import config from '@/config'
import store from '@/store'
require('echarts/extension/bmap/bmap')

export default {
  mixins: [chartResize],
  props: {
    className: {
      type: String,
      default: ''
    },
    id: {
      type: String,
      default: 'effect-scatter-map'
    },
    options: {
      type: Object,
      default: null
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    defaultColor: {
      type: String,
      default: '#ffff00'
    },
    defaultSymbolSize: {
      type: Number,
      default: 5
    },
    mapData: {
      type: Array,
      default: null
    },
    topNum: {
      type: Number,
      default: 0
    },
    fetchData: {
      type: Function
    },
    collapseIcon: {
      type: Boolean
    },
    pointMultiple: {
      type: Number,
      default: 1
    },
    level: {
      type: Array,
      default: null
    },
    centerPoint: {
      type: Array
    },
    markPoint: {
      type: Array,
      default: null
    },
    rangeParams: {
      type: Object,
      default: null
    }
  },
  computed: {
    wrapId() {
      return this.id + '-chart'
    }
  },
  watch: {
    mapData: {
      handler() {
        this.chartRest()
      },
      deep: true
    },
    topNum() {
      !isEmpty(this.mapData) && this.chartRest()
    },
    collapseIcon() {
      this.chartRest()
      window[this.id].resize()
    },
    pointMultiple() {
      !isEmpty(this.mapData) && this.chartRest()
    },
    centerPoint() {
      this.chartRest()
    },
    rangeParams() {
      this.chartRest()
    },
    markPoint() {
      this.chartRest()
      this.$nextTick(() => {
        this.setMapMark()
      })
    }
  },
  mounted() {
    const that = this
    let timeFn = null
    window[this.id] = echarts.init(document.getElementById(this.id), config.echartsthemeName)
    window[this.id].on('click', function(params) {
      clearTimeout(timeFn)
      timeFn = setTimeout(function() {
        that.pointClickHandle(params)
      }, 300)
    })
    window[this.id].on('dblclick', function(params) {
      that.closeBMapZoom() // 是否关闭地图缩放功能
      clearTimeout(timeFn)
      that.pointDbllickHandle(params)
    })
    this.initChart()
    if (isFunction(this.fetchData)) {
      this.getMapData()
    }
  },
  beforeDestroy() {
    if (!window[this.id]) {
      return
    }
    window[this.id].off('click')
    window[this.id].dispose()
    window[this.id] = null
  },
  methods: {
    chartRest() {
      if (this.mapData.length > 0) {
        window[this.id].clear()
      }
      window[this.id].hideLoading()
      this.$nextTick(() => {
        this.initChart()
      })
    },
    /**
     * desc: 当开启双击地图覆盖物的时候，关闭地图的双击放大
     * param {type}
     * return:
     */
    closeBMapZoom() {
      const {
        _events: { pointDblclick }
      } = this
      if (pointDblclick) {
        const bMap = window[this.id]
          .getModel()
          .getComponent('bmap')
          .getBMap()
        bMap.disableDoubleClickZoom() // 关闭地图缩放功能
      }
    },
    /**
     * 获取分布图数据
     * @return {[type]} [description]
     */
    getMapData() {
      window[this.id].showLoading({
        text: '地图规划中,请稍后。。。',
        color: '#2d8cf0',
        textColor: '#2d8cf0',
        maskColor: 'rgba(33, 40, 72,.9)',
        zlevel: 10
      })
      this.fetchData()
    },
    /**
     * @msg: 覆盖数据筛选
     * @param {type}
     * @return:
     */
    convertData(data) {
      const errPonts = []
      each(data, item => {
        const { value } = item
        if (value[2] > this.topNum) {
          errPonts.push(item)
        }
      })
      return errPonts
    },
    /**
     * description: 范围异常点
     * param {type}
     * return:
     */
    convertRangeData(data) {
      // 当设置了异常范围点之后进行数据筛选，否则不显示异常范围点
      if (!this.rangeParams || isEmpty(this.rangeParams)) {
        return []
      }
      const { min, max } = this.rangeParams
      const rangePoints = []
      each(data, item => {
        const { value } = item
        if (isNaN(parseInt(max))) {
          if (value[2] > min) {
            rangePoints.push(item)
          }
        } else {
          if (value[2] > min && value[2] <= max) {
            rangePoints.push(item)
          }
        }
      })
      return rangePoints
    },
    symbolPointSize(val) {
      if (!this.level || isEmpty(this.level)) return this.defaultSymbolSize * this.pointMultiple
      let r = ''
      for (let i = 0; i < this.level.length; i++) {
        const { max } = this.level[i]
        if (val[2] === max) {
          r = i + 1
          break
        }
      }

      return r * this.pointMultiple
    },
    /**
     * @msg: 添加覆盖物
     * @param {type}
     * @return:
     */
    setMapMark() {
      const bMap = window[this.id]
        .getModel()
        .getComponent('bmap')
        .getBMap()
      const allOverlays = bMap.getOverlays()
      bMap.removeOverlay(allOverlays[0])
      // eslint-disable-next-line no-undef
      const point = new BMap.Point(...this.markPoint)
      // eslint-disable-next-line no-undef
      let marker = new BMap.Marker(point) // 创建标注
      bMap.addOverlay(marker) // 将标注添加到地图中
      bMap.getPanes().markerPane.style.zIndex = 500
      // eslint-disable-next-line no-undef
      marker.setAnimation(BMAP_ANIMATION_BOUNCE) // 跳动的动画
    },
    /**
     * @msg: 地图初始化
     * @param {type}
     * @return:
     */
    initChart() {
      const that = this
      const center = that.centerPoint || store.getters.mapCenter
      window[this.id].setOption(
        merge(
          {
            backgroundColor: 'transparent',
            tooltip: {
              trigger: 'item',
              formatter: function(val) {
                return '<div><h5>表具ID</h5>' + val.name + '</div>'
              }
            },
            bmap: {
              center: center,
              zoom: 13,
              roam: true,
              enableDrawingTool: true,
              mapStyle: {
                styleJson: config.mapStyleJson
              }
            },
            series: [
              {
                name: '表具ID',
                type: 'scatter',
                coordinateSystem: 'bmap',
                data: that.mapData,
                animation: false,
                symbolSize: function(val) {
                  return that.symbolPointSize(val)
                },
                label: {
                  formatter: '{b}',
                  position: 'right',
                  show: false
                },
                itemStyle: {
                  color: function(val = {}) {
                    if (!that.level || isEmpty(that.level)) return that.defaultColor
                    let currentColor = ''
                    for (let i = 0; i < that.level.length; i++) {
                      const { max, color } = that.level[i]
                      if (val.value[2] === max) {
                        currentColor = color
                        break
                      }
                    }
                    return currentColor
                  }
                },
                emphasis: {
                  label: {
                    show: false
                  }
                }
              },
              {
                name: '异常点',
                pointSize: 6,
                blurSize: 6,
                type: 'effectScatter',
                coordinateSystem: 'bmap',
                data: that.convertData(that.mapData),
                symbolSize: function(val) {
                  return that.symbolPointSize(val)
                },
                animation: false,
                showEffectOn: 'render',
                rippleEffect: {
                  brushType: 'stroke'
                },
                hoverAnimation: true,
                label: {
                  formatter: '{b}',
                  position: 'right',
                  show: false
                },
                itemStyle: {
                  color: function() {
                    if (!that.level || isEmpty(that.level)) return that.defaultColor
                    const { color } = that.level[that.level.length - 1]
                    return color
                  },
                  shadowBlur: 10,
                  shadowColor: '#333'
                },
                zlevel: 1
              },
              {
                name: '范围异常点',
                pointSize: 6,
                blurSize: 6,
                type: 'effectScatter',
                coordinateSystem: 'bmap',
                data: that.convertRangeData(that.mapData),
                symbolSize: function(val) {
                  const { pointRadius = 1 } = that.rangeParams
                  return pointRadius * that.defaultSymbolSize
                },
                animation: false,
                showEffectOn: 'render',
                rippleEffect: {
                  brushType: 'stroke'
                },
                hoverAnimation: true,
                label: {
                  formatter: '{b}',
                  position: 'right',
                  show: false
                },
                itemStyle: {
                  color: '#ff0000',
                  shadowBlur: 10,
                  shadowColor: '#333'
                },
                zlevel: 1
              },
              {
                name: '当前点',
                type: 'effectScatter',
                coordinateSystem: 'bmap',
                data: that.currentPotin(that.mapData, this.centerPoint),
                animation: false,
                showEffectOn: 'render',
                rippleEffect: {
                  brushType: 'stroke'
                },
                symbolSize: 30,
                symbol: 'pin',
                hoverAnimation: true,
                label: {
                  formatter: '{b}',
                  position: 'right',
                  show: false
                },
                itemStyle: {
                  color: '#33ff00'
                },
                zlevel: 2
              }
            ]
          },
          that.options
        ),
        true
      )
    },
    /**
     * @msg: 当前选中点
     * @param {type}
     * @return:
     */
    currentPotin(data, point) {
      if (isEmpty(point) || isEmpty(data)) {
        return ''
      }
      for (let i = 0; i < data.length; i++) {
        const val = data[i].value
        const lp = [val[0], val[1]]
        if (isEqual(lp, point)) {
          return [data[i]]
          // eslint-disable-next-line no-unreachable
          break
        }
      }
      return ''
    },
    /**
     * @msg: 点击覆盖物
     * @param {type}
     * @return:
     */
    pointClickHandle(params) {
      this.$emit('pointClick', params)
    },
    /**
     * description: 地图双击点
     * param {type}
     * return:
     */
    pointDbllickHandle(params) {
      this.$emit('pointDblclick', params)
    }
  }
}
</script>
<style lang="less">
.effect-scatter-map-wrap {
  .chart {
    width: 100%;
    height: 100%;
  }
}
</style>
